package org.hk.kg.db;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.Connection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hk.kg.db.annotations.StatusMsg;
import org.hk.kg.db.annotations.Transaction;
import org.hk.kg.ui.KGUiContext;

public class DBServiceInvocationHandler implements InvocationHandler {
	private Object target;
	private static Log logger = LogFactory.getLog(DBServiceInvocationHandler.class);
	public DBServiceInvocationHandler(Object target)
	{
		this.target = target;
	}
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Transaction trans = method.getAnnotation(Transaction.class);
		StatusMsg msgs = method.getAnnotation(StatusMsg.class);
		if(msgs != null)
		{
			KGUiContext.instance.setStatusTxt(msgs.beginMsg());
		}
		
		Object rlt = null;
		if(trans != null)
		{
			String dbname = trans.dbname();
			Connection connection = DBContext.instatnce.connectMap.get(dbname);
			if(connection == null)
			{
				try
				{
					rlt = method.invoke(target, args);
				}
				catch(Exception e)
				{
					logger.error(e);
					KGUiContext.instance.setStatusTxt(msgs.errMsg());
				}	
			}
			else
			{
				connection.setAutoCommit(false);
				try
				{
					rlt = method.invoke(target, args);
					logger.debug("Transaction " + target.getClass().getName() + "[" + method.getName() + "]");
					connection.commit();
				}catch(Exception e){
					logger.error(e);
					connection.rollback();
					KGUiContext.instance.setStatusTxt(msgs.errMsg());
				}
				connection.setAutoCommit(true);
			}
		}
		else
		{
			try
			{
				rlt = method.invoke(target, args);
			}
			catch(Exception e)
			{
				logger.error(e);
				KGUiContext.instance.setStatusTxt(msgs.errMsg());
			}
		}
		KGUiContext.instance.setStatusTxt(msgs.endMsg());
		return rlt;
	}
}
